1. /* sdfddadd.cpp by K.Tsuru */
  2. // function ID = 321 DRADIX
  3. /********************************************
  4. SDouble class
  5. m + n, same sign
  6. Provides an addition of two absolute values.
  7. It must consider the case such as
  8. 0.0000 abcd efgh .... wxyz ( = m)
  9. + 0.0000 .... 0000 ABCD EFGH .... WXYZ( = n).
  10. ********************************************/
  11. #ifndef SN_H
  12. #include "sn.h"
  13. #endif
  14. static const char* func = "DDAdd";
  15. SDouble DDAdd(const SDouble& m, const SDouble& n){
  16. if((m.Type() != m.REAL)||(n.Type() != n.REAL)) m.SetError(m.RADIX_ERR, func, 321);
  17. if(m.Sign(321) == 0) return n;
  18. if(n.Sign(321) == 0) return m;
  19. //same sign
  20. if( m.Sign() != n.Sign() ) m.SetError(m.SYNTAX_ERR, func, 321);
  21. //check m >> n || m << n
  22. //"long" type is necessary in the 16 bits system.
  23. long di = (long)m.NetRdxExp() - (long)n.NetRdxExp(); //difference in exponent
  24. long max_fig = (long)m.CurrentMaxSize() -1;
  25. if( labs(di) >= max_fig) return di > 0 ? m : n;
  26. int de = m.rdxExp - n.rdxExp;
  27. //When de < 0, exchange m <--> n.
  28. if(de < 0) return DDAdd(n, m);
  29. const fType* Mf = m.ReadFigures();
  30. const fType* Nf;
  31. SDouble result, N; // radix = DRADIX only
  32. uint ml = m.Last(), mf = m.First(), nl, nf;// ml < CurrentMaxSize()
  33. int top, btm;
  34. // step 1 : make the exponents the same value
  35. if(!de){ //same exponent
  36. Nf = n.ReadFigures(); nl = n.Last(); nf = n.First();
  37. } else {
  38. N = n;
  39. N.ShiftArray(de);//moving figures, size is extended if necessary
  40. N.rdxExp += de;
  41. if(N.Sign(321) == 0) return m; //check n << m again
  42. Nf = N.ReadFigures(); nl = N.Last(); nf = N.First();
  43. }
  44. uint rsize = max(ml, nl) +1u;
  45. result.valloc(rsize , -1); //allocate memory, not initialize
  46. result.figure.clear(rsize); //initialize lower region
  47. fType* rf = result.figure.Elements();
  48. // step 2 : copy lower part of longer number to that of result
  49. if(ml < nl){ // n is longer
  50. memcpy(rf+ml+1u, Nf+ml+1u, (nl-ml)*sizeof(fType));
  51. } else if(ml > nl){
  52. memcpy(rf+nl+1u, Mf+nl+1u, (ml-nl)*sizeof(fType));
  53. }
  54. // step 3 : addition of the part in which both figures are non-zero
  55. register int i;
  56. fType w = 0;
  57. top = (int)max(mf, nf);
  58. btm = (int)min(ml, nl);
  59. #ifndef NDEBUG
  60. result.figure(btm); // error check
  61. assert(top > 0);
  62. #endif
  63. for(i = btm; i >= top; i--){
  64. w += Mf[i] + Nf[i];
  65. rf[i] = w % DRADIX;
  66. w /= DRADIX;
  67. }
  68. // step 4 : upper region of m and/or n is filled by zero
  69. top = (int)min(mf, nf);
  70. int end = 0; //addition has ended?
  71. if(mf != nf){
  72. Mf = (mf < nf) ? Mf : Nf;
  73. for(;w && (i >= top); i--){ //while carry is not clear
  74. w += Mf[i];
  75. rf[i] = w % DRADIX;
  76. w /= DRADIX;
  77. }
  78. //copy residual figures
  79. if(w == 0){
  80. memcpy(rf, Mf, (i+1)*sizeof(fType));
  81. end = 1; i = 0;
  82. }
  83. }
  84. // step 5 : disposal of carry to highest figure
  85. if(w){
  86. for(; i >= top; i--){ //normalize only, a few times
  87. rf[i] = w % DRADIX;
  88. w /= DRADIX;
  89. }
  90. }
  91. if(!end) result.figure[i] = w; //carry, including w = 0
  92. if(i) result.figure.clear(0, uint(i-1));//fill upper region with zero
  93. //Get the position.
  94. result.aTail = w ? (uint)i : (uint)top;
  95. register uint h;
  96. h = max(ml, nl); // != last
  97. while(!rf[h]) h--;
  98. result.aHead = h;
  99. //Set sign and exponent.
  100. result.SetSign(m.Sign()); result.rdxExp = m.rdxExp;
  101. result.Reform(321); //clear the carry to figure[0], etc.
  102. return result;
  103. }

sdfddadd.cpp : last modifiled at 2017/03/13 14:31:58(3,388 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).